<?php
namespace app\apps\model;
use app\apps\model\Apps;
class Vote extends Apps{
    protected $tableName = 'vote';
    protected $vote_id = 0;//当前操作的投票标识
    protected function tableSql($tableName = ''){
        $sql.= " CREATE TABLE IF NOT EXISTS `zb_vote` (";
        $sql.= " `vote_id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '投票项目ID',";
        $sql.= " `uid` int(11) NOT NULL COMMENT '发起投票的用户UID',";
        $sql.= " `title` varchar(50) DEFAULT '' COMMENT '投票的标题',";
        $sql.= " `create_time` int(11) NOT NULL DEFAULT '0' COMMENT '投票项目创建时间',";
        $sql.= " `druation_time` int(11) NOT NULL DEFAULT '0' COMMENT '持续时间',";
        $sql.= " `ballot` int(11) NOT NULL DEFAULT '0' COMMENT '投票总数',";
        $sql.= " `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '投票状态 1:正在投票 2:投票临时关闭 0:投票结束',";
        $sql.= " PRIMARY KEY (`vote_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"; 
        $table['vote'] = $sql;
        $sql = "CREATE TABLE IF NOT EXISTS `zb_vote_options` (";
        $sql.= " `option_id` bigint(18) unsigned NOT NULL AUTO_INCREMENT COMMENT '投票选项ID',";
        $sql.= " `vote_id` int(11) NOT NULL COMMENT '对应的投票项目ID',";
        $sql.= " `option_key`  varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '投票选项key' ,";
        $sql.= " `option_value`  varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '投票选项值' ,";
        $sql.= " `option_ballot` int(11) NOT NULL DEFAULT '0' COMMENT '当前选项的投票总数',";
        $sql.= " PRIMARY KEY (`option_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;";
        $table['vote_options'] = $sql;
        unset($sql);
        return ($tableName && array_key_exists($tableName,$table)) ? $table[$tableName] : $table;
    }
   protected function _initialize(){}
    /**
     * @name 自动修复表方法
     */
    protected function initTable($tableName = ''){
        if(false === $this->hasTable($tableName)){
            $sql = $this->tableSql($tableName);
            return $this->execute($sql);
        }
        return 0;
    }
    /**
     * @name 发起投票
     */
    public function createVote($data = []){
        $this->initTable('vote');
        $this->initTable('vote_options');
        //分析选项
        $options = $this->parseVoteOptions($data['options']);
        if(count($options) < 2){
            $this->error = '投票选项不能少于两项';
            return false;
        }
        $vote = [
            'uid' => $data['uid'],
            'title' => $data['title'],
            'create_time' => NOW_TIME,
            'druation_time' => $data['time'] ? (int)$data['time'] * 60 : 0
        ];
        if($this->vote_id = $this->add($vote)){
            $options = $this->parseVoteOptions($data['options']);
            if(M('vote_options')->addAll($options)){
                return $this->getVoteByUid($data['uid']);
            }
        }
        $this->error = '发起投票失败,请重试';
        return false;
    }
    /**
     * @name 分析投票选项
     */
    public function parseVoteOptions($options = ''){
        if($options){
            $options = array_filter(array_unique(explode(',',$options)));
            foreach($options as $k=>&$v){
                if(false !== strpos($v,':')){
                    $option = explode(':',$v);
                }else{
                    $option = [
                        0 => '',
                        1 => $v
                    ];
                }
                $v = [
                    'option_key' => $option[0],
                    'option_value' => $option[1],
                    'vote_id' => $this->vote_id
                ];
            }
            unset($v);
            return array_filter($options);
        }
    }
    /**
     * @name 获取最后一次投票
     */
    public function getVoteByUid($uid = 0){
        $return = [];
        if($uid){
            $vote = $this->where('uid='.$uid)->order('create_time desc')->find();
            if($vote){
                $this->vote_id = $vote['vote_id'];
                $return = [
                    'vote_id' => 'v-'.jiami($this->vote_id.'t'.$vote['create_time']),
                    'create_time' => $vote['create_time'],
                    'title' => $vote['title'] ?: '',
                    'time' => $vote['druation_time']/60,
                    'ballot' => (int)$vote['ballot'],
                    'status' => (int)$vote['status']
                ];
                $return['options'] = $this->getVoteOptions();
                if($return['status'] !== 0 && $vote['create_time'] + $vote['druation_time'] <= NOW_TIME){
                    $this->endVote($this->vote_id);
                    $return['status'] = 0;
                }
            }
        }
        return $return;
    }
    /**
     * @name 获取投票的选项
     */
    public function getVoteOptions($vote_id = 0){
        $vote_id = $vote_id ?:$this->vote_id;
        $return = [];
        if($vote_id){
            $options = M('vote_options')->where('vote_id='.$vote_id)->order('option_id asc')->select();
            foreach($options as $v){
                $option = [
                    'option_key' => $v['option_key'] ?:'op_'.$v['option_id'],
                    'option_value' => $v['option_value'],
                    'option_ballot' => (int)$v['option_ballot']
                ];
                array_push($return,$option);
            }
        }
        return $return;
    }
    /**
     * @name 添加投票
     */
    public function addAallot($vote_id = 0 ,$option_key = '',$count = 0,$uid = 0){
        if($vote_id && $option_key && $count && $uid){
            $this->vote_id = $vote_id;
            $this->option_key = $option_key;
            //检测vote_id
            if($this->checkVoteId() !== true){
                return false;
            }
            //检测选项
            if($this->checkOptionKey() !== true){
                $this->error = '投票失败,不存在该项投票';
                return false;
            }
            $to_uid = $this->getUidByVoteId();
            if($uid == $to_uid){
                $this->error = '不能为自己投票';
                return false;
            }
            //检测金币数量,并扣除金币
            $userModel = model('open/UserData');
            $userModel->checkUserData($uid);
            $giftGold = model('stream/Gift');
            if (true === $giftGold->goldDec($uid, $count)) {
                
                //请求客户服务器
                $log = [
					'num' => $count,
					'to_usid' => model('open/User')->getUsidByUid($to_uid), //收款方
					'usid' => model('open/User')->getUsidByUid($uid), //支出方
					'type' => 'gold',
                    'order' => date('YmdHi',NOW_TIME).mt_rand(100000,999999),
					'description' => '参与投票',
                    'order_type' => 'vote',
                    'ctime' => NOW_TIME
				];
                M('gift_give_log')->add($log);
                $res = $userModel->checkUserPay($log);
                if($res === true){
                    //同步数据
                    $userModel->checkUserData($to_uid,true);
                    $userModel->checkUserData($uid,true);
                    //投票:选项票数  总票数
                    if($this->ballotInc($this->option_key,$count) === true){
                        return true;
                    }
                }
                
            }else{
                $this->error = $giftGold->getError();
                return false;
            }
        }
        $this->error = '投票失败,请稍后再试';
        return false;
    }
    /**
     * @name 检测投票
     */
    public function checkVoteId($vote_id = 0){
        $vote_id = $vote_id ?: $this->vote_id;
        if(!is_numeric($vote_id)){
            if(substr($vote_id,0,2) !== 'v-'){
                return false;
            }
            $vote_id = jiemi(substr($vote_id,2));
            $t = strripos($vote_id,'t');
            
            $vote_id = (int)substr($vote_id,0,$t);
        }
        //检测失败存在ID
        if(!$this->hasVote($vote_id)){
            $this->error = '投票失败,不存在该投票';
            return false;
        }
        $this->vote_id = $vote_id;
        $status = $this->getVoteStatus($vote_id);
        if($status === 0){
            $this->error = '投票已经结束';
            return false;
        }elseif($status === 2){
            $this->error = '投票临时关闭,请稍后再试';
            return false;
        }
        $time = (int)$this->getFieldByVoteId($vote_id,'druation_time');
        //时间检测
        if($time > 0){
            if($this->getVoteCreateTime($vote_id) + $time <= NOW_TIME){
                $this->endVote($vote_id);
                $this->error = '投票失败,已超过投票时间';
                return false;
            }
        }
        return true;
        
    }
    /**
     * @name 是否正在投票
     */
    public function isPolling($vote_id = 0){
        return $this->getFieldByVoteId($vote_id,'status') == 1 ? true : false;
    }
    /**
     * @name 投票的状态
     */
    public function getVoteStatus($vote_id = 0){
        return (int) $this->getFieldByVoteId($vote_id,'status');
    }
    /**
     * @name 检测投票ID失败存在
     */
    public function hasVote($vote_id = 0){
        return $this->where('vote_id='.$vote_id)->count() > 0 ? true : false;
    }
    /**
     * @name 获取某次投票的发起时间
     */
    public function getVoteCreateTime($vote_id = 0){
        if($vote_id){
            return (int)$this->getFieldByVoteId($vote_id,'create_time');
        }
        return 0;
    }
    /**
     * @name 检测投票选项
     */
    public function checkOptionKey($option_key = ''){
        $option_key = $option_key ?: $this->option_key;
        if($option_key){
            $where = strpos($option_key,'op_') === false ? ['option_key'=>$option_key] : ['option_id' => str_replace('op_','',$option_key)];
            $where['vote_id'] = $this->vote_id;
            return M('vote_options')->where($where)->count() > 0 ? true : false;
        }
        return false;
    }
    /**
     * @name 操作票数
     */
    public function ballotInc($option_key = '',$count = 0){
        if($option_key && $count){
            $where = strpos($option_key,'op_') === false ? ['option_key'=>$option_key] : ['option_id' => str_replace('op_','',$option_key)];
            $where['vote_id'] = $this->vote_id;
            if(M('vote_options')->where($where)->setInc('option_ballot',$count)){
                return (boolean)$this->where(['vote_id'=>$this->vote_id])->setInc('ballot',$count);
                
            }
        }
        return false;
    }
    /**
     * @name 根据投票id,返回投票信息
     */
    public function getVoteByVoteId($vote_id = 0){
        if(substr($vote_id,0,2) !== 'v-'){
            return [];
        }
        $vote_id = jiemi(substr($vote_id,2));
        $t = strripos($vote_id,'t');
        
        $id = (int)substr($vote_id,0,$t);
        //检测失败存在ID
        if(!$this->hasVote($id)){
            return [];
        }
        $ctime = (int)substr($vote_id,$t+1);
        $vote = $this->where(['vote_id'=>$id])->order('create_time desc')->find();
        $return = [];
        if($vote && $vote['create_time'] == $ctime){
            $this->vote_id = $vote['vote_id'];
            $return = [
                'vote_id' => 'v-'.jiami($this->vote_id.'t'.$vote['create_time']),
                'create_time' => $vote['create_time'],
                'title' => $vote['title'] ?:'',
                'time' => $vote['druation_time']/60,
                'ballot' => (int)$vote['ballot'],
                'status' => (int)$vote['status']
            ];
            $return['options'] = $this->getVoteOptions();
            if($return['status'] !== 0 && $vote['druation_time'] !=0 && $vote['create_time'] + $vote['druation_time'] <= NOW_TIME){
                $this->endVote($this->vote_id);
                $return['status'] = 0;
            }
        }
        return $return;
    }
    /**
     * @name 分析并取得真实的vote_id
     */
    public function getRealVoteId($vote_id = 0){
        if(!is_numeric($vote_id)){
            if(substr($vote_id,0,2) !== 'v-'){
                return [];
            }
            $vote_id = jiemi(substr($vote_id,2));
            $t = strripos($vote_id,'t');
            
            $vote_id = (int)substr($vote_id,0,$t);
            //检测失败存在ID
            if(!$this->hasVote($vote_id)){
                $vote_id = 0;
            }
        }
        return $vote_id;
    }
    /**
     * @name 检测是不是发起人
     */
    public function isInitiator($uid = 0 , $vote_id){
        if($uid && $vote_id){
            return $this->getFieldByVoteId($vote_id,'uid') == $uid ? true : false;
        }
        return false;
    }
    /**
     * @name 结束投票
     */
    public function endVote($vote_id = 0){
        if($vote_id && $this->getVoteStatus($vote_id) !== 0){
            return $this->where(['vote_id' => $vote_id])->setField('status',0) ? true : false;
        }
        return true;
    }
    /**
     * @name 临时关闭投票
     */
    public function endVoteTemp($vote_id = 0){
        if($vote_id && $this->getVoteStatus($vote_id) !== 2){
            if($this->isPermanentEnd($vote_id) === true){
                $this->error = '投票已经结束,无法操作';
                return false;
            }
            return $this->where(['vote_id' => $vote_id])->setField('status',2) ? true : false;
        }
        return true;
    }
    /**
     * @name 恢复投票
     */
    public function startVoteTemp($vote_id = 0){
        if($vote_id && $this->getVoteStatus($vote_id) !== 1){
            if($this->isPermanentEnd($vote_id) === true){
                $this->error = '投票已经结束,无法操作';
                return false;
            }
            return $this->where(['vote_id' => $vote_id])->setField('status',1) ? true : false;
        }
        return true;
    }
    /**
     * @name 检测投票是否被永久关闭
     */
    public function isPermanentEnd($vote_id = 0){
        if($vote_id){
            return $this->getFieldByVoteId($vote_id,'status') == 0 ? true : false;
        }
        return true;
    }
    /**
     * @name 设置时间
     */
    public function setVoteTime($vote_id = 0 ,$time = ''){
        if($vote_id && is_numeric($time)){
            if($this->isPermanentEnd($vote_id) === true){
                $this->error = '投票已经结束,无法操作';
                return false;
            }
            $act = ($time == 0) ? 'setField' : (($time > 0) ? 'setInc' : 'setDec');
            $time = abs($time) * 60;
            if($act == 'setDec' && $this->getFieldByVoteId($vote_id,'druation_time') <= $time ){
                return 1;
            }
            return $this->where(['vote_id' => $vote_id])->$act('druation_time',$time) ? 1 : 0;
        }
        return 1;
    }
    /**
     * @name 根据投票ID返回发起者uid
     */
    public function getUidByVoteId($vote_id = 0){
        $vote_id = $vote_id ?:$this->vote_id;
        if($vote_id){
            return $this->getFieldByVoteId($vote_id,'uid');
        }
        return 0;
    }
    
    /**
     * @name 结束某主播发起的投票
     */
    public function endVoteByUid($uid = 0){
        if($uid){
            $map['uid'] = $uid;
            $map['status'] = ['neq',0];
            return $this->where($map)->setField('status',0);
        }
        return 0;
    }
}